import { Button, DatePicker, Modal, Select, Table } from "antd";
import SearchIcon from "@/assets/icons/search.svg?jsx";
import type { IDeviceOperationLog } from "@/lib/types";
import { useEffect, useMemo, useRef, useState } from "react";
import { useAtomValue } from "jotai";
import { tokenAtom } from "@/store/user";
import useFetch from "@/lib/hooks/useFetch";
import { getDeviceList } from "@/lib/api/device";
import useOnMounted from "@/lib/hooks/useOnMounted";
import { getDeviceOperationLogs } from "@/lib/api/log";
import { useMessage } from "@/providers/AntdMessageProvider";
import useOnUpdated from "@/lib/hooks/useOnUpdated";
import clsm from "@/lib/utils/clsm";

type OperationProps = {
  // deviceList: IDevice[];
  // isDeviceListLoading: boolean;
  visible: boolean;
};
export default function Operation(props: OperationProps) {
  const { visible } = props;
  const [searchData, setSearchData] = useState({
    device: null as number | null,
    time: null as string[] | null,
  });
  const [pagination, setPagination] = useState({
    index: 1,
    size: 10,
    total: 0,
  });
  const [parameterModal, setParameterModal] = useState({
    visible: false,
    log: null as IDeviceOperationLog | null,
  });
  const token = useAtomValue(tokenAtom);
  const message = useMessage();

  const {
    isLoading: isDeviceListLoading,
    data: deviceList,
    refetch: loadDeviceList,
    cancel: cancelLoadDeviceList,
  } = useFetch({
    fetchFn: (
      payload: { pageNum: number; pageSize: number },
      signal: AbortSignal,
    ) =>
      getDeviceList(payload, token, signal).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
        return res.rows;
      }),
  });

  const {
    isLoading: isLogLoading,
    data: log,
    refetch: loadLogs,
    cancel: cancelLoadLogs,
  } = useFetch({
    fetchFn: (
      data: Parameters<typeof getDeviceOperationLogs>[0],
      signal: AbortSignal,
    ) =>
      getDeviceOperationLogs(data, token, signal).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
        setPagination((p) => ({ ...p, total: res.total }));
        return res.rows;
      }),
  });

  function handleSearch() {
    if (!searchData.device) {
      message.error("请选择设备！");
      return;
    }
    if (!searchData.time) {
      message.error("请选择时间！");
      return;
    }
    cancelLoadLogs();
    loadLogs({
      pageSize: pagination.size,
      pageNum: pagination.index,
      deviceId: searchData.device,
      startTime: searchData.time[0],
      endTime: searchData.time[1],
    });
  }

  useOnUpdated(() => {
    handleSearch();
    return () => {
      cancelLoadLogs();
    };
  }, [pagination.index, pagination.size]);

  useEffect(() => {
    if (visible && !deviceList) {
      loadDeviceList({ pageNum: 1, pageSize: 999 });
    }
    return () => {
      cancelLoadDeviceList();
    };
  }, [visible, deviceList, loadDeviceList, cancelLoadDeviceList]);

  return (
    <>
      <div className={clsm(!visible && "hidden")}>
        <div className="flex justify-center gap-x-4">
          <Select
            loading={isDeviceListLoading}
            value={searchData.device}
            style={{ width: 200 }}
            onChange={(v) => setSearchData((p) => ({ ...p, device: v }))}
            allowClear
            showSearch
            optionFilterProp="label"
            placeholder="选择设备"
          >
            {deviceList?.map((device) => (
              <Select.Option
                key={device.deviceId}
                label={device.deviceName}
                value={device.deviceId}
              >
                {device.deviceName}
              </Select.Option>
            ))}
          </Select>
          <DatePicker.RangePicker
            showTime
            onChange={(v) =>
              setSearchData((p) => ({
                ...p,
                time:
                  v && v[0] && v[1]
                    ? [
                        v[0].format("YYYY-MM-DD HH:mm:ss"),
                        v[1].format("YYYY-MM-DD HH:mm:ss"),
                      ]
                    : null,
              }))
            }
          />
          <Button loading={isLogLoading} onClick={handleSearch}>
            <SearchIcon />
          </Button>
        </div>
        <div className="mt-8 px-10">
          <Table
            loading={isLogLoading}
            dataSource={log || []}
            rowKey="operId"
            pagination={{
              total: pagination.total,
              current: pagination.index,
              pageSize: pagination.size,
              onChange(index, size) {
                setPagination((p) =>
                  p.size === size
                    ? { ...p, index, size }
                    : { ...p, index: 1, size },
                );
              },
            }}
          >
            <Table.Column title="操作人" dataIndex="deptName" />
            <Table.Column title="操作名称" dataIndex="title" />
            <Table.Column title="时间" dataIndex="operTime" />
            <Table.Column
              title="状态"
              render={(row) => <span>操作{row.status ? "失败" : "成功"}</span>}
            />
            <Table.Column
              title="操作参数"
              render={(row) => (
                <Button
                  type="text"
                  onClick={() =>
                    setParameterModal({
                      visible: true,
                      log: row,
                    })
                  }
                >
                  查看
                </Button>
              )}
            />
          </Table>
        </div>
      </div>
      <OperationParameterModal
        visible={parameterModal.visible}
        log={parameterModal.log}
        onClose={() => setParameterModal({ visible: false, log: null })}
      />
    </>
  );
}

type OperationParameterModalProps = {
  visible: boolean;
  log?: IDeviceOperationLog | null;
  onClose: () => void;
};
function OperationParameterModal(props: OperationParameterModalProps) {
  const { visible, log, onClose } = props;

  const elRef = useRef<HTMLDivElement>(null);
  const jsonStr = useMemo(() => {
    if (!log) {
      return "";
    }
    return JSON.stringify(JSON.parse(log.operParam), null, 2);
  }, [log]);

  useEffect(() => {
    if (visible) {
      setTimeout(() => {
        elRef.current!.scrollTop = 0;
      });
    }
  }, [visible]);

  return (
    <Modal
      title="操作参数"
      open={visible}
      onCancel={onClose}
      maskClosable={false}
      footer={
        <div className="flex justify-center">
          <Button onClick={onClose} type="primary">
            关闭
          </Button>
        </div>
      }
    >
      <div className="max-h-[50vh] overflow-auto whitespace-pre" ref={elRef}>
        {jsonStr}
      </div>
    </Modal>
  );
}
